package com.sdk.apiNotify.rabbitmq.producer;

import com.coment.dto.ApiNotify;
import com.coment.dto.LiveData.ApiType;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import com.sdk.apiNotify.TopicCfg;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

import java.util.Arrays;

@Slf4j
@Service
@AllArgsConstructor
public class ApiNotifyProducer {
    private final AmqpTemplate amqpTemplate;
    private TopicCfg topicCfg;
    private AmqpAdmin amqpAdmin;

    @Bean
    public Exchange liveTopicExchange() {
        Exchange liveTopicExchange = ExchangeBuilder.topicExchange(this.topicCfg.topic).durable(true).build();
        this.amqpAdmin.declareExchange(liveTopicExchange);
        DirectExchange dlxExchange = ExchangeBuilder.directExchange(this.topicCfg.topicDlx).durable(true).build();
        this.amqpAdmin.declareExchange(dlxExchange);
        this.amqpAdmin.deleteQueue(this.topicCfg.topicRetry);
        this.amqpAdmin.deleteQueue(this.topicCfg.topicDlx);
        Queue dlxQueue = QueueBuilder.durable(this.topicCfg.topicDlx).build();
        this.amqpAdmin.declareQueue(dlxQueue);
        Binding dlxBinding = BindingBuilder.bind(dlxQueue).to(dlxExchange).with(this.topicCfg.topicDlx);
        this.amqpAdmin.declareBinding(dlxBinding);
        Queue retryQueue = QueueBuilder.durable(this.topicCfg.topicRetry).withArgument("x-dead-letter-exchange", this.topicCfg.topicDlx).withArgument("x-dead-letter-routing-key", this.topicCfg.topicDlx).withArgument("x-buffInfo-ttl", 6000).build();
        this.amqpAdmin.declareQueue(retryQueue);
        Arrays.stream(ApiType.values()).forEach((apiType) -> {
            String queueName = String.format("%s.%s", this.topicCfg.topic, apiType.name());
            Queue queue = QueueBuilder.durable(queueName).withArgument("x-dead-letter-exchange", this.topicCfg.topicRetry).build();
            this.amqpAdmin.declareQueue(queue);
            Binding binding = BindingBuilder.bind(queue).to(liveTopicExchange).with(String.format("%s.%s.#", this.topicCfg.topic, apiType.getValue())).noargs();
            this.amqpAdmin.declareBinding(binding);
            log.info("已初始化平台队列: {}", queueName);
        });
        return liveTopicExchange;
    }

    public void sendMessage(ApiNotify apiNotify) {
        try {
            String routingKey = String.format("%s.%s", this.topicCfg.topic, apiNotify.getApiType().getValue());
            this.amqpTemplate.convertAndSend(this.topicCfg.topic, routingKey, apiNotify);
        } catch (Exception e) {
            log.error("推送消息到 RabbitMQ 失败", e);
        }

    }

    public void sendToRetryQueue(ApiNotify ApiNotify) {
        try {
            this.amqpTemplate.convertAndSend("", this.topicCfg.topicRetry, ApiNotify);
            log.info("推送消息到重试队列成功: {}", this.topicCfg.topicRetry);
        } catch (Exception e) {
            log.error("推送消息到重试队列失败", e);
        }

    }

    public void sendToDeadLetterQueue(ApiNotify ApiNotify) {
        try {
            this.amqpTemplate.convertAndSend(this.topicCfg.topicDlx, this.topicCfg.topicDlx, ApiNotify);
            log.info("推送消息到死信队列成功: {}", this.topicCfg.topicDlx);
        } catch (Exception e) {
            log.error("推送消息到死信队列失败", e);
        }

    }

    public void sendToRetryQueueWithHeaders(ApiNotify ApiNotify) {
        try {
            this.amqpTemplate.convertAndSend("",  this.topicCfg.topicRetry, ApiNotify);
        } catch (Exception e) {
            log.error("推送消息到重试队列失败", e);
        }
    }
}
